<?php

namespace app\common\model\shop;

use app\common\model\BaseModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\facade\Db;

/**
 * 门店导购
 * Class ShopSalesman
 * @package app\common\model\shop
 */
class ShopSalesmanModel extends BaseModel
{
    //
    protected $name = 'shop_salesman';

    // 设置字段信息
    protected $schema = [
        'id' => 'int',        //
        'mer_id' => 'string',        // 所属商户
        'shop_id' => 'int',        // 所属店铺
        'name' => 'string',        // 姓名
        'mobile' => 'string',        // 联系电话
        'point' => 'int',        //
        'red_packet' => 'float',        // 当前红包金额
        'open_id' => 'string',        // 微信openid
        'union_id' => 'string',        // 微信union_id
        'nickname' => 'string',        // 微信昵称
        'address' => 'string',        // 详细地址
        'lat' => 'string',        // 经度
        'lng' => 'string',        // 纬度
        'op_user' => 'int',        // 操作人
        'create_at' => 'datetime',        // 创建时间
        'update_at' => 'datetime',        // 更新时间
    ];


    /**
     * 分页列表
     * @param $where
     * @param $page
     * @param $count
     */
    public function salesmanPage($where, $page = 1, $count = 30)
    {
        try {

            $shop = $this->db()->alias('a')
                ->join('shop s', 's.id=a.shop_id')
                ->where($where)
                ->field('a.id,a.shop_id,a.name,a.mobile,a.point,a.red_packet,a.scans_num,a.open_id,a.union_id,a.nickname,
                a.address,a.status,a.op_user,a.recheck,a.bind_wechat,s.title as shop_title')
                ->paginate(['page' => $page, 'list_rows' => $count]);

            if (isset($shop['data']) && !empty($shop['data'])) {
                $op_user_name = $this->db('merchant')->column('username', 'id');
                foreach ($shop['data'] as $key => $v) {
                    $shop['data'][$key]['op_user_name'] = $op_user_name[$v['op_user']] ?? '';
                }
            }

            return $shop;
        } catch (Exception $e) {
            throw   $e;
        }

    }


    /**
     * 列表
     * @param     $where
     * @param int $list
     * @return array|mixed
     * @throws Exception
     * @throws DbException
     */
    public function salesmanList($where, $list = 1)
    {
        try {

            return $this->db()->where($where)
                ->field('id,name,shop_id,mobile,nickname,address,open_id,status')
                ->limit($list)->select();
        } catch (Exception $e) {
            throw   $e;
        }

    }


    /**
     * 详情
     * @param $id
     */
    public function salesmanInfo($id)
    {
        try {

            $shop = $this->db()->alias('a')
                ->leftJoin('shop s', 's.id=a.shop_id')
                ->where('a.id', $id)
                ->field('a.id,a.shop_id,a.name,a.pics,a.mobile,a.point,a.red_packet,a.scans_num,a.open_id,a.union_id,a.nickname,
                a.address,a.op_user,s.title as shop_title,a.memo')->withAttr(['pics' => function($v){
                    if (!empty($v)){
                        return explode(',', $v);
                    }
                    return [];
                }])
                ->find();

            if (empty($shop)) {
                throw  new Exception('未找到门店', API_ERROR);
            }
            $shop['op_user_name'] = $this->db('merchant')
                ->where('id', $shop['op_user'])->value('username');
            return $shop;
        } catch (Exception $e) {
            throw   $e;
        }

    }


    /**
     *修改
     * @param $shop_id |门店
     * @param $mer_id | 商户
     * @param $name |昵称
     * @param $mobile |手机号
     * @param $id |
     */
    public function salesmanSave($shop_id, $mer_id, $name, $mobile, $id)
    {
        try {
            //验证店铺是否存在，获取店铺地址信息
            $shop = $this->db('shop')->where('mer_id', $mer_id)->where('id', $shop_id)->find();
            if (empty($shop)) {
                throw  new Exception('店铺未找到', 400);
            }
            $info = $this->db()->where('mer_id', $mer_id)->where(function ($query) use ($id, $mobile) {
                $query->where('id', $id)->whereOr('mobile', $mobile);
            })->field('id,mobile')->select();
            if (empty($info)) {
                throw  new Exception('导购信息未找到', 400);
            }
            if (count($info) > 1 || (int)$info[0]['id'] !== (int)$id) {
                throw  new Exception('手机号码已存在', 400);
            }
            $sales_info = $this->db()->where(['mer_id' => $mer_id , 'id' => $id])->find();
            if (empty($sales_info)) {
                throw  new Exception('导购信息未找到', 400);
            }
            if (!empty($sales_info['shop_id'])){
                $this->db('shop')->where('mer_id', $mer_id)->where('id', $sales_info['shop_id'])->update([
                    'sales_man_num' => Db::raw('sales_man_num-1')
                ]);
            }
            //更新
            $this->db()->where('id', $id)->update([
                'shop_id' => $shop_id,
                'name' => $name,
                'mobile' => $mobile,
            ]);
            $this->db('shop')->where('mer_id', $mer_id)->where('id', $shop_id)->update([
                'sales_man_num' => Db::raw('sales_man_num+1')
            ]);
            return true;
        } catch (Exception $e) {
            throw   $e;
        }

    }

    /**
     * 导购积分调整
     * @param     $id |主键
     * @param     $point |积分
     * @param     $memo
     * @param int $type |1添加， 2减少
     * @return bool
     * @throws DbException
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function salesmanSavePoint($id, $point, $memo, $type = 1)
    {
        $salesman = $this->db()->where('id', $id)->find();
        if ($type === 1) {
            $salesman_point = $salesman['point'] + $point;
        } else {
            if ($salesman['point'] < $point) {
                throw  new Exception('积分不足', API_ERROR);
            }
            $salesman_point = $salesman['point'] - $point;
        }

        $this->db()->where('id', $id)->update(['point' => $salesman_point]);
        $this->db('shop_salesman_point')->insert([
            'mer_id' => $salesman['mer_id'],
            'shop_id' => $salesman['shop_id'],
            'salesman_id' => $id,
            'point' => $point,
            're_point' => $salesman_point,
            'memo' => $memo,
        ]);
        return true;
    }

    /**
     *  检测登录的信息是否正确, 正确返回用户信息,失败返回空,错误信息放到msg中,
     * @param array $logininfo 要检测的登录信息
     * @param string $msg 接收返回的内容
     * @return array 返回的用户信息
     * @throws \think\Exception
     */
    public function validUserInfo(array $logininfo, &$msg): array
    {
        if (empty($logininfo["id"])) {
            $msg = '导购ID不能为空';
            return [];
        }
        $adminInfo = $this->where("id", $logininfo['id'])->where("status", 1)
//            ->cache(true, MINUTES_SECOND)
            ->find();
        if (empty($adminInfo)) {
            $msg = '导购不存在或已被禁用';
            return [];
        }
        $msg = "";
        return $adminInfo;
    }


    /**
     * 检测注册的信息,新增还是更新
     * @param string $mer_id 商户ID
     * @param string $open_id openID
     * @param string $mobile 手机号码
     * @return int
     * @throws DbException
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function validRegisterUserInfo(string $mer_id, string $open_id, string $mobile): int
    {
        $userList = $this->db()->where('mer_id', $mer_id)->where(function ($query) use ($open_id, $mobile) {
            $query->where('open_id', $open_id)->whereOr('mobile', $mobile);
        })->field('id,bind_wechat,open_id,union_id,mobile,recheck')->select();
        if (empty($userList)) {
            return 0;
        }
        if (count($userList) > 1) {
            throw  new  Exception('该微信已经注册导购,请勿重复注册,变更信息请联系经销商.', API_ERROR);
        }
        $info = current($userList);
        // 判断是是否已登记,登录未审核,可以更新信息
        if ($info['open_id'] === $open_id) {
            if ($info['recheck'] === 0) {
                return $info['id'];
            }
            throw  new  Exception('该微信已经注册导购,请勿重复注册,变更信息请联系经销商.', API_ERROR);

        }

        if ($info['mobile'] === $mobile) {
            if ($info['bind_wechat'] === 1 || !empty($info['open_id']) || !empty($info['union_id'])) {
                throw  new  Exception('该手机已经绑定.无法重复绑定', API_ERROR);
            }
            return $info['id'];
        }
        return 0;
    }

    /**
     * 验证导购距离是否在该范围内
     * @param $open_id |导购$open_id
     * @param $mer_id |商户id
     * @param $lng1 |经度1
     * @param $lat1 |纬度1
     * @return bool
     * @throws DbException
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function validDistance($open_id, $mer_id, $lng1, $lat1): bool
    {

        $shop_info = $this->db('merchant_info')->where(['mer_id' => $mer_id])->find();
        if ($shop_info['restrict_location'] !== 1) {
            return true;
        }
        $user_info = $this->db()->removeOption()->where(['mer_id' => $mer_id, 'open_id' => $open_id])->find();
        if ($shop_info['distance'] < 1) {
            return true;
        }

        if (empty($user_info['lng']) || empty($user_info['lat'])) {
            throw  new Exception('请先设置扫码位置', API_ERROR);
        }

        if (empty($lng1) || empty($lat1)){
            throw  new Exception('请开启手机定位 .', API_ERROR);
        }
        $m = getDistance($lng1, $lat1, $user_info['lng'], $user_info['lat']);
        if (!$m  || $m > $shop_info['distance']){
            throw  new Exception('您当前位置不在可扫码范围内,请回到您注册的位置再扫码.', API_ERROR);
        }
        return true;
    }


    /**
     * 获取导购信息
     * @param array $where | 筛选条件
     * @return array 返回的用户信息
     * @throws Exception
     */
    public function getSalesmanUserInfo(array $where, $field): array
    {
        $user_info = $this->db()->where($where)->field($field)
//            ->cache(true, MINUTES_SECOND_5)
            ->find();
        if (empty($user_info)) {
            throw  new Exception('用户不存在或已被禁用', API_ERROR);
        }
        return $user_info;
    }

    /**
     * 获取导购的信息
     * @param int $userid
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getSalesManInfo(int $userid)
    {
        return $this->db()->where('id', $userid)
            ->where('status', 1)
            ->field('name,mobile,shop_id,open_id,union_id,point,red_packet,scans_num')
            ->find();
    }

    /**
     * 检查手机号是否存在
     * @param string $mer_id
     * @param string $mobile
     * @return int|mixed|string|null
     */
    public function checkMobile(string $mer_id, string $mobile)
    {
        if (empty($mer_id) || empty($mobile)) {
            return 0;
        }
        return $this->where('mer_id', $mer_id)->where('mobile', $mobile)->value([], 'id');
    }


    /**
     *  保存用户信息
     * @param array $post_data 提交的数据
     * @param array $wx_info 微信信息
     * @return int
     * @throws DbException
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function saveUserInfo(array $post_data, array $wx_info): array
    {
        $result = [];
        $id = $this->validRegisterUserInfo($post_data['mer_id'], $post_data['open_id'], $post_data['mobile']);
        if ($id === 0) {
            $data = array_merge($post_data, $wx_info);
            $data['bind_wechat'] = 1;
            $data['status'] = 0;
            $data['nickname'] = $wx_info['nick_name'];
            $data['pics'] = implode(',',$post_data['pics']);
            $id = $this->insertGetId($data);
            $result['msg'] = '您的信息已提交，请通知供货商审核. ';
        } else {
            $this->db()->where('id', $id)->update([
                'nickname' => $wx_info['nick_name'] ?? '',
                'head_img' => $wx_info['head_img'] ?? '',
                'open_id' => $post_data['open_id'] ?? '',
                'union_id' => $wx_info['union_id'] ?? '',
                'lng' => $post_data['lng'],
                'lat' => $post_data['lat'],
                'bind_wechat' => 1,
                'update_at' => date('Y-m-d H:i:s'),
                'name' => $post_data['name'],
                'shop_id' => $post_data['shop_id'] ?? 0,
                'memo' => $post_data['memo'] ?? '',
                'address' => $post_data['address'] ?? '',
                'pics' => implode(',',$post_data['pics']),
            ]);
            $result['msg'] = '您的信息已更新，请通知供货商审核.';
        }
        $result['id'] = $id;
        return $result;
    }


    /**
     *  分页列表
     * @param     $where |条件
     * @param int $page |分页
     * @param int $page_size |数量
     * @throws Exception
     */
    public function salesmansPage($where, int $page = 1, int $page_size = 30)
    {

        return $this->db()->where($where)->order('update_at desc,create_at desc')
            ->field('id,shop_id,name,mobile,point,red_packet,scans_num,open_id,union_id,nickname, address,status,
            op_user,recheck,bind_wechat,head_img,pics,create_at')->withAttr('pics' , function ($v){
                return explode(',',$v);
            })
            ->paginate(['page' => $page, 'list_rows' => $page_size]);

    }

    /**
     * 根据Openid 获取导购信信
     * @param string $merId 商户号
     * @param string $openid openid
     * @return array [result=>true,status =>3,'type'=>0,msg=>'','info'=>[]]
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function getSalesManForOpenId(string $merId, string $openid): array
    {
        $result = [
            'sale_man' => false,
            'status' => true,
            'type' => 0,
            'msg' => '',
            'id' => 0,
            'info' => []
        ];
        $shoppers = $this->db()->where('mer_id', $merId)->where('open_id', $openid)
            ->field('id,shop_id,mer_id,name,open_id,union_id,status,recheck')
            ->find();

        // 判断导购信息是否为空
        if (!empty($shoppers)) {
            $result['id'] = $shoppers['id'];
            $result['info'] = $shoppers;
            $result['sale_man'] = true;
            if ((int)$shoppers['recheck'] !== 1) {
                $result['type'] = 3;
                $result['status'] = false;
                $result['msg'] = '未审核,请联系管理员审核';
            } elseif ((int)$shoppers['status'] !== 1) {
                $result['status'] = false;
                $result['msg'] = '导购已禁用,请联系管理员.';
                $result['type'] = 4;
            }
        }
        return $result;
    }

    /**
     * 获取商户下导购数量
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function shopSalesmanList()
    {
        return $this->db()->group('mer_id')
            ->column('count(id) as count','mer_id');
    }
}
